//!@author denglibin
//!@date 2025/6/3 15:45
//!@desc

use crate::dao::mysql::mysql_dao;
use crate::dao::sqlite::sqlite_dao;
use crate::dao::sqlserver::sql_server_dao;
use crate::entity;
use crate::sys::global::{to_global_result, GlobalError, GlobalResult};
use log::info;
use my_trait::{MustHaveFieldType, MustHaveTableName, Struct2Map};
use redis::streams::StreamInfoGroup;
use serde::Serialize;
use sqlx::mysql::MySqlRow;
use sqlx::{FromRow, SqlitePool, Value};
use tiberius::Client;
use tokio::net::TcpStream;
use tokio_util::compat::Compat;

///导入到sqlite 自动建表
pub async fn sqlserver2sqlite_auto(
    sqlserver_client: &mut Client<Compat<TcpStream>>, //sqlserver客户端
    up_column_name: &str, //增量字段名称 数值类型 不重复 作为 sqlite的主键
    up_column_start_val: i64, //增量字段开始值
    table_name: &str, //表名
    sqlite_db: &str, //sqlite路径
    size: usize, //导出数量
) -> GlobalResult<()> {
    let sqlite_conn_pool: sqlx::Pool<sqlx::Sqlite> = sqlite_dao::get_conn_pool(sqlite_db).await?;
    let mut is_create_table: bool = false;

    let mut start_value: i64 = up_column_start_val;

    let mut count = 0;

    let column_types = sql_server_dao::get_table_columns(table_name, sqlserver_client).await?;
    let columns = column_types
        .iter()
        .map(|column_type| {
            if (column_type.1.contains("varchar")) {
                //转换编码方式
                return format!(
                    "CAST(\"{}\" AS NVARCHAR(MAX)) AS \"{}\"",
                    column_type.0, column_type.0
                );
            };
            return column_type.0.to_string();
        })
        .collect::<Vec<String>>();
    loop {
        let sql = format!(
            "select top 200 {} from {} where {} > {} order by {} asc",
            columns.join(","),
            table_name,
            up_column_name,
            start_value,
            up_column_name
        );
        // info!("sql:{}", sql);
        //字段和数据
        let (columns, mut rows) =
            to_global_result(sql_server_dao::select_list(&sql, sqlserver_client).await)?;

        if rows.is_empty() {
            break;
        }

        if !is_create_table {
            create_sqlite_table(table_name, &columns, up_column_name, &sqlite_conn_pool).await?;
            is_create_table = true;
        }

        info!("rows len:{}", rows.len());

        let up_column_index = find_up_column_index(up_column_name, &columns)?;

        start_value = rows
            .last()
            .unwrap()
            .get(up_column_index)
            .unwrap()
            .to_string()
            .parse()
            .unwrap();

        if count + rows.len() > size {
            //排除多余的
            rows.drain((size - count)..rows.len());
        }

        sqlite_dao::insert_batch_data(table_name, &columns, &rows, &sqlite_conn_pool).await?;
        count += rows.len();

        info!("进度:{}", count);

        if count >= size {
            break;
        }
    }

    Ok(())
}

///创建sqlite数据库
async fn create_sqlite_table(
    table_name: &str,
    columns: &Vec<String>,
    up_column_name: &str,
    sqlite_conn_pool: &SqlitePool,
) -> GlobalResult<()> {
    let columns_types = columns
        .iter()
        .map(|column| {
            let column_name = column;
            let mut column_type = "text";
            if column == up_column_name {
                column_type = "integer primary key";
            }
            return (column_name.to_string(), column_type.to_string());
        })
        .collect::<Vec<(String, String)>>();

    let column_types = columns_types
        .iter()
        .map(|item| format!("[{}] {}", item.0, item.1))
        .collect::<Vec<String>>()
        .join(",");
    let create_table_sql = format!("create table {}({})", table_name, column_types);
    info!("sqlite table:{}", create_table_sql);
    sqlite_dao::create_tabale(create_table_sql.as_str(), sqlite_conn_pool).await
}

fn find_up_column_index(up_column: &str, columns: &Vec<String>) -> GlobalResult<usize> {
    let mut index = 0;
    for column in columns {
        if up_column == column {
            return Ok(index);
        }
        index += 1;
    }
    Err(anyhow::anyhow!("增量字段索引未找到".to_string()))
}
